It would depend on the exact needs and the system.
You need to review the system and locate the bottlenecks. With other words, what should be cached, what need to be cached, what cant be cached etc.
It is also important to find out how long you can use the cache before it should expire, and if there is any cases the cache should expire before this; if the user updated something etc.
When you know all of that, you can sit down and figure out the best cache solution for the system in mind.
You need to create a caching system that is agile enough to cover all of the options you need. What we did was to create one based on the adapter pattern, this allows us to switch to any caching solution according to the specific needs, so one system can implement different solutions for different parts of the system, and even for the same call.
It is also important that the system is able to separate different users, parts of websites etc from each other, this allows you to cache user only content without fearing that it can be shown to any others than the user that it belong to. You can also decide to only cache a small part of a page, larger part, or multiple parts of it as required.
I guess the most important thing to remember, is that there is no “one solution fits all”.
ESI (Edge Side Includes) was pretty much developed for user vs guest & personalised content.
Allows you to split a response(page) into several fragments, and have different caching characteristics, and assembled at request time with something like Varnish.