I just amazed myself with the following.
/// <summary>
/// Find the smallest enclosing circle. See reference
/// http://www.inf.ethz.ch/personal/emo/PublFiles/SmallEnclDisk_LNCS555_91.pdf
/// "Smallest enclosing disks (balls and ellipsoids) EMO WELZL
/// </summary>
/// <returns></returns>
public static class Circles 
{
    private static Return<Circle> Left
        (List<Point2D> points, List<Point2D> boundary)
    {
        if ( !points.Any() || boundary.Count == 3 )
        {
            if ( boundary.Count <= 1 )
            {
                return Return.Value<Circle>(null);
            }
            if ( boundary.Count == 2 )
            {
                var radius = boundary[0].DistanceTo(boundary[1]) / 2;
                var center = ( boundary[0] + boundary[1] ) * 0.5;
                return Return.Value(new Circle(Plane.XY, center, radius));
            }
            return Return.Value(new Circle(Plane.XY, boundary[0], boundary[1], boundary[2]));
        }
        var p = points[0];
        var q = points.GetRange(1, points.Count - 1);
        return from circle in Return.Call(() => Left(q, boundary))
               from result in 
                   (circle == null || circle.Center.DistanceTo(p) >= circle.Radius)
                           ? Return.Call(() => Left(q, boundary.Concat(p).ToList()))
                           : Return.Value(circle)
               select result;
    }
    public static Circle MiniDisk( List<Point2D> points )
    {
        points = points.Slice(0);
        points.Shuffle();
        return TrampolineRecursion.Do(()=>LeftLeft(points, new List<Point2D>()));
    }
}
using the following implementation of the Trampoline monad I just magicked up.
namespace Weingartner.Numerics.Recursion
{
    public class Return<T>
    {
        #region return value mode
        public bool HasReturnValue;
        public T ReturnValue;
        #endregion
        #region call and continue mode
        public Func<Return<T>> Call;
        public Func<T, Return<T>> Continue;
        #endregion
        /// <summary>
        /// To avoid GC pressure we use a thread static variable
        /// to handle the return value from functions.
        /// </summary>
        [ThreadStatic] private static Return<T> _ReturnRegister;
        public static Return<T> R()
        {
            if (_ReturnRegister == null)
            {
                _ReturnRegister = new Return<T>();
            }
            return _ReturnRegister;
        }
        public Return<T> Bind(Func<T, Return<T>> fn)
        {
            if (HasReturnValue)
                return Return.Call(() => Return.Value(ReturnValue), fn);
            if(Continue!=null)
                return Return.Call(Call, t => Continue(t).SelectMany(fn));
            return Return.Call(Call, fn);
        }
        public Return<T> SelectMany(Func<T, Return<T>> fn)
        {
            return Bind(fn);
        }
        public Return<T> SelectMany( Func<T, Return<T>> f, Func<T, T, T> g)
        {
            return Bind(x => f(x).Bind(y => Return.Value(g(x, y))));
        }
        public Return<T> Select(Func<T, T> fn)
        {
            if (HasReturnValue)
                return Return.Value(fn(ReturnValue));
            if(Continue!=null)
                return Return.Call(Call, t => Continue(t).Select(fn));
            return Return.Call(Call, t => Continue(t).Select(fn));
        }
        public T Run()
        {
            var stack = new Stack<Func<T,Return<T>>>();
            if(Continue!=null)
                stack.Push(Continue);
            stack.Push(r => Call());
            var @return = Return.Value(default(T));
            while ( stack.Count > 0 )
            {
                @return = stack.Peek()(@return.ReturnValue);
                stack.Pop();
                if (!@return.HasReturnValue)
                {
                    if(@return.Continue!=null)
                        stack.Push(@return.Continue);
                    var t = @return;
                    stack.Push(r => t.Call());
                }
            }
            return ReturnValue = @return.ReturnValue;
        }
    }
    public class Return
    {
        public static Return<T> Value<T>( T t )
        {
            var r = Return<T>.R();
            r.HasReturnValue = true;
            r.ReturnValue = t;
            return r;
        }
        public static Return<T> Call<T>
            (Func<Return<T>> call, Func<T, Return<T>> @continue = null)
        {
            var r = Return<T>.R();
            r.HasReturnValue = false;
            r.Call = call;
            r.Continue = @continue;
            return r;
        }
    }
    public static class TrampolineRecursion
    {
        public static T Do<T>(Func<Return<T>> call)
        {
            return Return.Call(call).Run();
        }
    }
}