Miners could agree not to build on purposefully empty or too small blocks. If the majority complies, the risk of getting an empty block ignored by the network costs too much. This could be done informally...
I wonder if it could also be done formally (as in enforced by the protocol).
I proposed an idea like yours on another thread about establishing informal "best-practices" for filling each block (however, I never suggested that miners ignore blocks from those who break the guidelines). It could be informally agreed upon, for example, to use a proportional feedback controller to determine the block_size for the current block you're working on
block_size = avg_blocksize_last_diff_period +
K1 x (unconfirmed_transactions_kB - target_unconfirmed_transactions_kB)
where K1 is a gain parameter.
But I've always wondered if you could actually enforce this at the protocol level (not that I think it would necessarily be a good thing if you could) by using "block_size > … " rather than an "block_size = ...". The parameter "avg_blocksize_last_diff_period" is deterministic (full nodes and miners will be in 100% agreement) and K1 is static. If we also set
target_unconfirmed_transactions_kB = K2 x avg_blocksize_last_diff_period
this parameter becomes deterministic too. The only thing the network will not agree on is the precise value of unconfirmed_transacations_kB. However, well-connected nodes should all be in loose agreement here. In order for a miner to have his block accepted, he will be motivated to add a bit more transactions than are strictly necessary to ensure that his peers accept it (because their value of "unconfirmed_transactions_kB" may be slightly larger) but not too much more TXs in order to minimize his chance of having his block orphaned.
The question is whether this algorithm would be stable and byzantine robust for certain values of K1 and K2.