Checking for data on the I2C bus (without Wire.h)

Certainly, the issue is only that the code is quite exhaustive. Nevertheless, here goes:
Setting up the slave:

void initTwiSlave(uint8_t addr)
{

	PORTC |=  _BV(5) | _BV(4);	// enable pullups

	TWAR = (0<<TWGCE) |((uint8_t) (0xff & (addr<<1)));    // set slave address, no general call address
	TWDR = 0xff; // Default content = SDA released

	TWCR =	(1<<TWINT)	|	// "clear the flag"  (clear I2C interrupt)
			(1<<TWEA)	|	// send acks to master when getting address or data
			(0<<TWSTA)	|	// not a master, cant do start (don't generate start condition)
			(0<<TWSTO)	|	// Don't generate stop condition (doc says set these to 0)
          	(0<<TWWC)	|
			(1<<TWEN)	|	// hardware I2C enabled
			(0<<TWIE);		// disable I2C interrupts

	while (TWCR & (1<<TWIE)) { }	// wait for the I2C transceiver to get ready /

}

Reading a byte from I2C:

uint8_t getTwiByte(void)
{
	uint8_t result=0;

  	keepListening:

 	// wait for an state change
  	while (!(TWCR & (1<<TWINT))) { } // wait for TWINT to be set


  	//uint8_t sr = TWSR;
  	switch (TWSR)
  	{
	    case TWI_SRX_ADR_DATA_ACK:  // received a byte of data data
	    case TWI_SRX_GEN_DATA_ACK:
			result = TWDR;
	      	TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWEA);
			break;


//        case TWI_SRX_GEN_ACK_M_ARB_LOST:
//        case TWI_SRX_ADR_ACK_M_ARB_LOST:
    	case TWI_SRX_GEN_ACK:
    	case TWI_SRX_ADR_ACK:      // receive our address byte
		      TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWEA);
		      goto keepListening;
		      break;

	    case TWI_SRX_STOP_RESTART:       // A STOP or repeated START condition was received
	    	TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWEA);
		    goto keepListening;
	      	break;

	    case TWI_SRX_ADR_DATA_NACK:   // data received, returned nack
	    case TWI_SRX_GEN_DATA_NACK:
	      	TWCR = (1<<TWEN)|(1<<TWINT);
	      	goto keepListening;
			break;

    	case TWI_NO_STATE:
    		goto keepListening;
    		break;

	    default:     			 // something bad happened. assuming a bus error, we try to recover from this
	      // reset state and continue
	      TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWEA)|(1<<TWSTO);    // ignore
		  while(TWCR & (1<<TWSTO)){ }	// wait for stop condition to be exectued; TWINT will not be set after a stop
		  result = 0xff;
	      break;
    }
		abortFlag = false; //debug debug

	return result;
}

Managing the I2C input (this function never returns):

void serviceInputData(void)
{
	uint8_t *ptr = frameBuffer;
	uint8_t state = 0;
	int counter = 0;
	while (1)
	{
		uint8_t c = getTwiByte();

		// very simple state machine to look for 6 byte start of frame
		// marker and copy bytes that follow into buffer
		if (state  <6)	// state < 6 means we are not in the process of receiving frameBuffer data from MegaMan
		{
         	/*
         	 *	We examine the byte we get from I2C, looking to see if we're building up a 0xdeadbeef1? header
         	 *	Once we have 0xdeadbeef1 (we're then in state 5) we look at the following byte. If it is 1, we
         	 *	read one more byte and execute the corresponding built-in graphical function with runCommand(),
         	 *	if *not*, we get ready run display a 325B frameBuffer that follows from I2C, i.e. then we are in
         	 *	"slave" mode, simply displaying whatever MegaMan sends us, until we have displayed one full
         	 *	frameBuffer and we start looking for a new header again
         	 */

			if      (state == 0 && c == 0xde) state++;	// switching state to 1
			else if (state == 1 && c == 0xad) state++;	// switching state to 2
			else if (state == 2 && c == 0xbe) state++;	// switching state to 3
			else if (state == 3 && c == 0xef) state++;	// switching state to 4
			else if (state == 4 && c == 0x01) state++;	// switching state to 5 (from the next byte we determine what to do with the data)

      		else if (state == 5 && c == 0x01) {			// state is 5 AND we have a command header (0xdeadbeef11)
      			runCommand(getTwiByte());				// sending the next byte, after de-ad-be-ef-01-01, to runCommand();
      			state = 0; 								// command executed, resetting state and starting over
      		} else if (state == 5 ) { 					// state is 5, but NO command header (0xdeadbeef10)
				state++; 								// switching to state 6
				counter = 0;							// preparing the byte counter for transmission of 325B frameBuffer
				ptr = frameBuffer;						// pointing ptr to beginning of Peggy's frameBuffer
			} else state = 0; 							// error: deviation from 0xdeadbeef1?, reset and start over

		} else {
			// inside of a frame, so save each byte to buffer - this is "slave mode" where we blindly display what MegaMan sends us
			*ptr++ = c;	// insert most recently read byte from I2C into frameBuffer on Peggy
			counter++;
			if (counter >= DISP_BUFFER_SIZE) {
				// buffer filled, so reset everything to wait for next frame
				counter = 0;
				ptr = frameBuffer;
				state = 0;
			}
		}
	}	// eternal while loop - never ends
}

As you can see here, the runCommand(getTwiByte()); is what we call if we want to run an animation. This is a large function that for every animation, does the if(abortFlag) return; in every iteration. Once the flag is set, it returns here.

Finally the interrupt. Notice that only the first couple of lines relate to the I2C, the rest is the screen update, but I included it to get it in context. The comented out lines are different approaches I tried. All to no avail.

ISR (TIMER0_COMPA_vect)
{

	//if ( (TWCR & (1<<TWINT)) && (TWSR == TWI_SRX_ADR_DATA_ACK) ) abortFlag = true;
	if (TWSR == TWI_SRX_ADR_DATA_ACK) abortFlag = true;
	//if (TWCR & (1<<TWINT)) abortFlag = true;
	//if (TWDR == 0xde) abortFlag = true;

	/*
	*	There are 15 passes through this interrupt for each row per frame - ( 15 * 25) = 375 times per frame.
	*	during those 15 passes, a led can be on or off.
	*	if it is off the entire time, the perceived brightness is 0/15
	*	if it is on the entire time, the perceived brightness is 15/15
	*	giving a total of 16 average brightness levels from fully on to fully off.
	*	currentBrightness is a comparison variable, used to determine if a certain
	*	pixel is on or off during one of those 15 cycles.
	*	currentBrightnessShifted is the same value left shifted 4 bits:  This is just an optimization for
	*	comparing the high-order bytes.
	*/
	if (++currentBrightness >= MAX_BRIGHTNESS)
	{
		currentBrightness=0;
		if (++currentRow > 24)
		{
			currentRow =0;
			currentRowPtr = frameBuffer;
		}
		else
		{
			currentRowPtr += 13;
		}
	}