The receiver part:

sub vcl_recv {
  # Wordpress - cache everything except...
  if (!(req.url ~ "wp-admin|xmlrpc\.php|wp-(comments-post|login|activate|mail)\.php|&preview=true")) {
    unset req.http.cookie;
    return (hash);

  # Happens before we check if we have this in cache already.
  # Typically you clean up the request here, removing cookies you don't need,
  # rewriting the request, etc.

The backend part:

sub vcl_backend_response {
  # Happens after we have read the response headers from the backend.
  # Here you clean the response headers, removing silly Set-Cookie headers
  # and other mistakes your backend does.

  # Wordpress - delete unnecessary before storing in cache
  if (!(bereq.url ~ "wp-admin|xmlrpc\.php|wp-(comments-post|login|activate|mail)\.php|&preview=true")) {
    unset beresp.http.set-cookie;
    unset beresp.http.cookie;
    unset beresp.http.expires;
    unset beresp.http.cache-control;
    unset beresp.http.pragma;
    set beresp.ttl = 1m;
    set beresp.grace = 1w;

This parts makes the client retry if they got an 503 Service Unavailable. This is practical if one backend suddenly went down.

sub vcl_backend_error {
  if (beresp.status == 503) {
    return (retry);

If you use SSL, this is almost required. Otherwise the default works well enough.

# Split plain and encrypted objects
sub vcl_hash {
  if ( {
  } else {

  # Use special internal SSL hash for https content
  # X-Forwarded-Proto is set to https by Pound
  if (req.http.X-Forwarded-Proto ~ "https") {

  return (lookup);

Without this we won't be able to cache completely.

sub vcl_hit {
  set req.http.grace = "full";