MicroCore, while only using a tiny amount of flash and RAM.
Although you can't use Serial.print, digitalRead, digitalWrite, analogRead, and analogWrite are all implemented. When the millis timer is not needed, it can be disabled to save space. When it is used, it takes about 60 bytes of flash thanks to my AVR assembler implementation. MicroCore also includes my optimized versions of shiftIn and shiftOut that are faster and smaller than the standard Arduino versions.
One thing that is missing from the MicroCore documentation is details on how small it is. An empty sketch takes just 46 bytes of flash and no RAM. A blink example using sleep and millis takes 154 bytes of flash and 5 bytes of RAM. The buttons example for my TM1638 library takes 266 bytes of flash and 0 bytes of RAM.
While has MicroCore has a software SPI implementation (TinySPI), it doesn't have I2C/Wire. I've been working on a bit-bang I2C library that is optimized for size and speed. On a 9.6Mhz ATtiny13 it runs at 660kHz. The next step before I release it is to make it as compatible as reasonably possible with the Arduino Wire library.
In addition to expanding the functionality of MicroCore, I'm hoping to simplify the use of millis so it is not linked in when it is not used. This would avoid having to modify core_settings.h, or clutter up the IDE menus with an option to enable/disable millis. I keep an eye on the github issues list for MicroCore, and will implement requested improvements that I find interesting.