Each process has several attributes that the process can set individually and independently from other processes. Examples are resource limits, umask, current directory, environment variables and some more. Upon process creation (by way of the fork() system call) the child inherits these attributes from the parent. After this the child process may set these attributes arbitrarily. (Some restrictions apply, a process may not increase hard resource limits or change its current directory to a directory for which it has no exec permission.)
Only few programs modify their environment variables, most don't bother. Suppose the latter case. So if a child process creates itself further children, then these processes will have the same environment variables as the grandparent. And so on.
Now, a shell has a lot of variables that can be viewed with set (in shells of Bourne Shell type, dunno about C Shell). These variables are not environment variables unless they are exported. Environment variables can be viewed with env. If you launch a program from the shell command line, the program will inherit the environment variables from the shell. Likewise for a program launched from a shell script.
Therefore, upon login there is a shell that reads profile data (e.g. ~/.profile) and inherits them to virtually all children, grandchildren and so on. This is how environment variable settings trickle down from the login shell or login script to all other programs launched within the login session.
I created a environment variable in one terminal window and tried to echo it in another terminal window. That displayed nothing.
By the above explanation, this is the expected result. Changes in the environment of a process affects only children of this process that are created henceforth, not existing ones.
$TEST=hello
This is unlikely to work anyway, unless variable expansion is disabled or $TEST has already a suitable value. If you want to assign hello to variable TEST then you have to say TEST=hello (note: no $).
After that I exported it and tried again to echo it in a different terminal window. result was same as before.
Once again, this is the expected result.
but if I execute the same code at the login (appending the code to ~/.profile file) variables can be used any terminal window.
This is because the shell in the terminal is a descendant of the shell that read the environment settings from ~/.profile and thus inherited these settings.