Na idéia geral os dois armazenam objetos em uma lista. Mas tem algumas diferença entre os dois. Vou mostrar algumas diferenças entre os dois em alguns exemplos, veja abaixo:

O primeiro exemplo vou utilizar o List<>(). Lista de STRING, mas poderia ser qualquer outro tipo!

Obs: Antes de começar o código abaixo, faça o using em:

System.Collections; Para utilizar o Stack.
System.Collections.Generic; Para utilizar o List<>.

Por padrão o System.Collections.Generic já vem declarado no VS 2008. Propriedades principais:

Add      -> Adiciona os objetos a lista.
RemoveAt -> Baseado no index remove o obejto.
Clear    -> Limpa toda a lista.
Sort     -> Ordena a lista.

List<string> Lista = new List<string>();
Lista.Add("Hello");
Lista.Add("World");
Lista.Add("Exemplo List<>");
Lista.Sort();

for (int i = 0; i < Lista.Count; i++)
   Console.WriteLine(Lista[i].ToString());


Assim seu display seria na ordem crescente:

Exemplo List<>
Hello
World

Para pesquisar um objeto na lista temos algumas recursos, vamos observar um deles: O FindIndex possui três sobrecargas, vamos ver cada uma delas:

Primeira Sobre Carga

for (int i = 0; i < Lista.Count; i++)
Console.WriteLine(String.Format("Indes {0}",                  Lista.FindIndex("Hello").ToString()));


Segunda Sobre Carga

for (int i = 0; i < Lista.Count; i++)
Console.WriteLine(String.Format("Indes {0}", Lista.FindIndex(i, "Nome").ToString()));

Terceira Sobre Carga

for (int i = 0; i < Lista.Count; i++)
Console.WriteLine(String.Format("Indes {0}", Lista.FindIndex(0, i, "World").ToString()));

Agora, para remover o objeto do LIST<>, um a um, basta fazer como exemplo abaixo:

for (int i = 0; i < Lista.Count; i++)
  Lista.RemoveAt(i);


Ou para limpar toda a lista.

Lista.Clear();
Console.WriteLine("---------------------------------------");


No segundo exemplo, vamos utilizar o Stack.  A idéia a mesma do List<>, sendo que a propriedade PUSH adiciona sempre o objeto que se segue no topo da lista. Propriedades principais:

Push -> Adiciona o objeto que se segue no topo da lista.
Pop   -> Mostrar os objetos da lista.
Peek -> Mostrar somente o objeto do topo da lista.

Stack S = new Stack();
S.Push("Hello");
S.Push("World");
S.Push("Just Testing");
for (int i = 0; i < 3; i++)
  Console.WriteLine(S.Pop().ToString());


 Assim seu display seria

Just Testing
World
Hello

Agora, para remover o objeto da lista STACK, basta fazer como exemplo abaixo:

S.Clear;
Console.Read();
 
Vimos nestas dicas alguns exemplos e diferenças entre estes dois objetos. Agora basta saber qual a melhor oportunidade para utilizar um ou a outra.
Ficai uma pequena dica!
Até mais;