Indeed, an account "exists" only after it has received a transaction, as far as Ethereum is concerned.
In going through all the blocks you are in effect re-doing what your Ethereum node has done to build the state of the EVM. It is an expensive way to build an index of all addresses, especially that most addresses will show up many times.
So instead, how about remembering that the state of the EVM, or rather the state's Merkle root, is stored in each block. And the state is, in part, made of all the "existing" addresses.
So you would be better off scanning the Merkle tree; in fact a Patricia trie, which has truncated branches where addresses are missing. Check out this answer ELI5 How does a Merkle-Patricia-trie tree work?