I ran into an interesting problem trying to migrate a design from the Mega8 to the Mega88. First of all, Atmel's app note fails to mention several differences including register problems, CLKPR (the clock prescaler), and more.
But, believe it or not, what killed the hardware migration was the fact they moved much of the I/O to the extended I/O area. This makes these registers unreachable by the IN and OUT instructions and you have to use STD and LDD instructions instead.
These are 4 byte instead of 2 byte instructions which makes your code bigger! Everywhere these extended registers are accessed requires 2 more bytes of code space (except the odd exception where the compiler or assembly programmer can use some tricks to use ST/STS instead).
The IN/OUT to STD/LDD is a lot of work for any code that was written in assembler. Once you start using the STD and LDD replacements, suddenly conditional branches are out of range, and you have even more code to modify and test.
Most of the I/O re-asignments are not because the Mega88 has vastly more on-chip peripherals compared to the Mega8. It's only because Atmel is trying to make the newer Mega devices more compatible with each other. So it's a bit frustrating!
I realize Atmel doesn't claim the Mega88 is a replacement for the Mega8, but it's something to watch out for if you were thinking of the Mega88. I also realize the Mega168 (with more code space) is another solution for some. In this case the code that didn't fit is in the bootloader section which doesn't get any bigger in the Mega168. So it killed the project. I hope they keep making the Mega8 for a long time!