Here's a stack exchange question:
https://monero.stackexchange.com/questions/2158/what-is-mone...
TL;DR Monero requires every transaction input to include a "key image" (an elliptic curve point, looks like a public key). The key image is deterministically constructed from the actual coin being spent, without actually revealing which one it is. So making sure the chain never contains a repeated key image is sufficient to make sure that no coin is ever spent more than once, without actually knowing whether any one specific coin is spent. This is how Monero achieves its inflation/non-cloning guarantee.
(There was a famous double-spending bug in CryptoNote protocols you might have heard about that resulted in limitless inflation. This was because the Ed25519 signature scheme used has a co-factor of 8, a stupid performance "enhancement" that DJB should really re-think. As a result, a given key-image had a 1-in-8 chance of being malleable by adding a point of order 8. It's fixed by checking that the key image is actually contained in the group. These sorts of unexpected consequences are why serious cryptographers don't use co-factors other than 1, or other fiddly tricks that get you small constant implementation gains with risky not well studied trade-offs. This is also why the current push to standardize on DJB designed crypto solutions is borderline insanity. But I digress.)
The mathematics of what zerocash does is wildly different, but it serves essentially the same purpose. Each private/anonymous spend in zerocash has some bits associated with it that are generated in a non-linking way from the input being spent. As long as there are never two transactions in the entire block chain history with the same value for this field, there are no double-spends.
-----
The problem is that these can never go away. In bitcoin if a coin is spent, you can prune knowledge of that coin from your local history. This is what the "-prune" option does in recent versions of Bitcoin Core. You still need to receive and process the transaction once when you sync the chain, but you can then throw it away if you are space constrained. Mimblewimble potentially improves the situation even better by boiling down each transaction to just a single EC point, the script kernel, such that a client needs only the current UTXO set and the full history of all these kernels to do initial sync. The rest of the data can well and truly be forgotten. But although those kernels are needed for initial sync, pruning nodes can throw them away afterwards. They are not needed for the validation of future blocks in any way.
TL;DR: The amount of data a verifier needs to keep around to validate a new block in bitcoin depends only on the number of unspent outputs. The full block chain is only needed for initial sync. This is asymptotically O(current size of bitcoin ecosystem). The amount of data needed by Monero or Zerocash, on the other hand, is (a constant factor of) the entire block chain used by these systems. This is asymptotically O(every transaction ever). Monero and ZCash are chugging along now, but every single block found increases the amount of data a verifier needs to keep around. That doesn't scale....