Receiving a whole string from USART on ATMEGA16?
Straight off I see two issues - one sneaky, and one which shows a bit of a lack of understanding.

The sneaky one is this line:

char REC;


REC is used within your interrupt and also outside your interrupt.  As such it has to be flagged as volatile or the compiler is at risk of optimizing it out as it doesn't know it's being changed by the ISR.

volatile char REC;


The second is how you deal with what's in REC:

while (REC !='\n')
{
    data[i++]=REC;
}


I send the letter "A" through the USART.  REC gets set to A.  Then in the main loop it goes:


Is REC different to "\n"?
Yes, it's A. Ok, I add that to data and increment i (i == 1).
Is REC different to "\n"?
Yes, it's A. Ok, I add that to data and increment i (i == 2).
Is REC different to "\n"?
Yes, it's A. Ok, I add that to data and increment i (i == 3).
Is REC different to "\n"?
Yes, it's A. Ok, I add that to data and increment i (i == 4).


... etc ...


Is REC different to "\n"?
Yes, it's A. Ok, I add that to data and increment i (i == 32767).
Is REC different to "\n"?
Yes, it's A. Ok, I add that to data and increment i (i == -32768).
Is REC different to "\n"?
Yes, it's A. Ok, I add that to data and increment i (i == -32767).


... and so on ... 

You have nothing to say "I have used the character that is currently in REC".

What you should instead be doing is clearing REC after each time you have consumed a character:

if (REC != 0) {
    if (REC == '\n') {
        // do whatever you want with the array contents
        i =0;
        data[0] = 0;
    } else {
        data[i++] = REC;
    }
    REC = 0;
} 


You should also check that i never gets too big and overflows your array.

An even better system would be to add the incoming character direct to the data array in the interrupt routine.  When you receive a \n you set a flag to tell the main loop that it's free to use the contents of the array (don't forget to clear that flag when you've used the contents).