Taken from this answer on Stack Overflow: 
[.htaccess mod_rewrite: rewriting querystring to path](https://stackoverflow.com/a/1219119/1013978)


    <IfModule mod_rewrite.c>
        RewriteEngine On

        # Remove index.php
        RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
        RewriteCond %{REQUEST_URI} !^/index\.php/admin\b [NC] # Don't mess with admin requests
        RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]

        # Remove ?p=
        RewriteCond %{THE_REQUEST} ^GET\ /\?(([^&\s]*&)*)p=([^&\s]+)&?([^\s]*)
        RewriteRule ^(.*)$ /%3?%1%4 [L,R=301]
  
        # Send would-be 404 requests to Craft
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
        RewriteRule (.+) index.php?p=$1 [QSA,L]
    </IfModule>

This not only reformats `/?p=about` as `/about`, but it also preserves other parts of the query string.

For example, `/?p=about&tag=stuff` and even `/?tag=stuff&p=about` both redirect to `/about?tag=stuff`.