Unfortunately LINQ to Entities currently does not support joins to inmemory collection, nor Contains for non primitive inmemory collection. The only way I see (actually there is another one described here Entity Framework LINQ Get all items part of another collection, but now I think this is more appropriate) is to construct OR filter using some expression build helper.
For instance, using the PredicateUtils class from Establish a link between two lists in linq to entities where clause, it could be like this:
First, add a little helper method
static Expression<Func<PropertyDetail, bool>> LocationFilter(string value, int index)
{
    if (!string.IsNullOrEmpty(value))
    {
        if (index == 0) return d => d.Continent == value;
        if (index == 1) return d => d.Country == value;
        if (index == 2) return d => d.State == value;
    }
    return null;
}
and then use
var locationsFilter = locations.Select(location => location.Select(LocationFilter)
    .Aggregate(PredicateUtils.And)).Aggregate(PredicateUtils.Or);
if (locationsFilter != null)
    query = query.Where(locationsFilter);
For completeness, here is the helper class used:
public static class PredicateUtils
{
    sealed class Predicate<T>
    {
        public static readonly Expression<Func<T, bool>> True = item => true;
        public static readonly Expression<Func<T, bool>> False = item => false;
    }
    public static Expression<Func<T, bool>> Null<T>() { return null; }
    public static Expression<Func<T, bool>> True<T>() { return Predicate<T>.True; }
    public static Expression<Func<T, bool>> False<T>() { return Predicate<T>.False; }
    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
    {
        if (Equals(left, right)) return left;
        if (left == null || Equals(left, True<T>())) return right;
        if (right == null || Equals(right, True<T>())) return left;
        if (Equals(left, False<T>()) || Equals(right, False<T>())) return False<T>();
        var body = Expression.AndAlso(left.Body, right.Body.Replace(right.Parameters[0], left.Parameters[0]));
        return Expression.Lambda<Func<T, bool>>(body, left.Parameters);
    }
    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
    {
        if (Equals(left, right)) return left;
        if (left == null || Equals(left, False<T>())) return right;
        if (right == null || Equals(right, False<T>())) return left;
        if (Equals(left, True<T>()) || Equals(right, True<T>())) return True<T>();
        var body = Expression.OrElse(left.Body, right.Body.Replace(right.Parameters[0], left.Parameters[0]));
        return Expression.Lambda<Func<T, bool>>(body, left.Parameters);
    }
    static Expression Replace(this Expression expression, Expression source, Expression target)
    {
        return new ExpressionReplacer { Source = source, Target = target }.Visit(expression);
    }
    class ExpressionReplacer : ExpressionVisitor
    {
        public Expression Source;
        public Expression Target;
        public override Expression Visit(Expression node)
        {
            return node == Source ? Target : base.Visit(node);
        }
    }
}
UPDATE: As requested in the comments, here is the solution for locations being List<Location>:
var locationsFilter = locations.Select(location =>
{
    var filter = PredicateUtils.Null<PropertyDetail>();
    if (!string.IsNullOrEmpty(location.Continent))
        filter = filter.And(d => d.Continent == location.Continent);
    if (!string.IsNullOrEmpty(location.Country))
        filter = filter.And(d => d.Country == location.Country);
    if (!string.IsNullOrEmpty(location.State))
        filter = filter.And(d => d.State == location.State);
    return filter;
}).Aggregate(PredicateUtils.Or);