Thanks to emielm, james and gabrielstuff for their excellent advice on this issue. I followed all instructions and got everything working as it should providing that I specifically set cache-control in the browser cache settings page to “private, no-cache, re-validate” for every page. Even then I still had the occasional problem where an item was added to the basket but when you went to the cart it was nowhere to be seen!
To solve this issue I would recommend unchecking “Enable AJAX add to cart buttons on archives” in Woocommerce settings in the catalog menu.
This will force the page to refresh when an item is added to the basket and the url will have “?added-to-cart=12345” at the end of it. It is not as slick as adding items via Ajax (without a page refresh) but it works! I’ve tried adding many items from different pages, deleting items, refreshing the page, changing quantities, pretty much everything possible to break the basket but cannot.
The added bonus is once you have done this you can then re-enable cache-control in the browser cache settings. To be on the safe side I have set mine to “public, must-revalidate, proxy-revalidate” but you might be able to get “expires with max-age” working. Make sure you have also unchecked “Cache URIs with query string variables” on the Page Cache settings page.
Providing that you have followed the other steps mentioned before this then you should notice a real benefit. The ultimate setup would be to use fragment caching but I haven’t experimented with this yet.