An alternative approach, which does not sacrifice the more common OOP style: https://www.doc.ic.ac.uk/%7Escd/ShapesOnwards.pdf
Not that I know an easy way to keep a lists of components that ensure that iterating over them is anywhere close to cache-efficient. Perhaps some kind of self-ordering system would work? (you could for instance move components to consecutive positions as a system uses them, ideally in way that's stable so you don't mess up the ordering of other systems)
It's basically free to do one stripe of bubble sort while iterating, and for games, you'll iterate everything once or more per frame, but introduce and delete things less.
Note that merely ordering isn't quite enough, let's say a particular system needs components ABC and component C is rare, then the ideal situation would be to sort A and B such that those entities with component C are close together.
The main mechanism seems to be for 'systems' being able to iterate over tuples of 'components' of a specific type for all 'entities'. I can't help but wonder if there isn't a more elegant way of doing this than trying to keep the set of entities for each system up to date. Though I suppose it depends on what you want to optimize.