And just for fun (almost a decade later) an answer also using Generics but with a Stack and While loop, based off the accepted answer by @vidstige.
public static class TypeExtentions
{
    public static IEnumerable<T> Descendants<T>(this T root, Func<T, IEnumerable<T>> selector)
    {
        var nodes = new Stack<T>(new[] { root });
        while (nodes.Any())
        {
            T node = nodes.Pop();
            yield return node;
            foreach (var n in selector(node)) nodes.Push(n);
        }
    }
    public static IEnumerable<T> Descendants<T>(this IEnumerable<T> encounter, Func<T, IEnumerable<T>> selector)
    {
        var nodes = new Stack<T>(encounter);
        while (nodes.Any())
        {
            T node = nodes.Pop();
            yield return node;
            if (selector(node) != null)
                foreach (var n in selector(node))
                    nodes.Push(n);
        }
    }
}
Given a collection one can use like this 
        var myNode = ListNodes.Descendants(x => x.Children).Where(x => x.Key == SomeKey);
or with a root object 
        var myNode = root.Descendants(x => x.Children).Where(x => x.Key == SomeKey);