Just Fixing the Issue:
You have to handle the case of an empty list in your recursion. A minimal (and admittedly somewhat hacky) change to your code would look something like this:
import sys 
def find(abc):
    #base case
    if len(abc) == 2:
        if isinstance(abc[0], list) and isinstance(abc[1], list):
            re = find(abc[0] + abc[1:])
        elif isinstance(abc[1], list):
            re = find(abc[:1] + abc[1])
        elif isinstance(abc[0], list):
            re = find(abc[0] + abc[1:])
            # ^^^ fixed typo (ifs could be simplified by dropping first if)
        else:
            if abc[0] > abc[1]:
                re = (abc[0], abc[1])
            else:
                re = (abc[1], abc[0])
    # recursive step
    else:
        # CHANGE HERE
        if len(abc) == 0:   # @HACK: handle empty list
            return (sys.maxsize, sys.maxsize)
        # CHANGE ENDS
        if isinstance(abc[0], list):
            re = find(abc[0] + abc[1:])
        # if this element is integer
        else:
            current = abc[0]
            second, first = find(abc[1:])
            if (second < current):
                re = (second, first)
            elif (current > first) and (second >= current):
                re = (current, first)
            else:
                re = (first, current)            
    return re # @TODO: possibly filter out maxsize in final result
This is far from perfect (e.g. yielding maxsize if there are not enough values and maybe having additional bugs). 
Refactoring Your Code: 
Therefore, I would refactor your code in two ways. Firstly, I would separate out flattening and searching (i.e. flatten first and then search the flattened list):
def flatten(li):
    for el in li:
        try:    # if strings can be in list, would have to check here
            for sub in flatten(el):
                yield sub
        except TypeError:
            yield el
def find(abc):
    abc = list(flatten(abc))
    def _smallest2(abc):
        # basically your implementation for finding the smallest two values
        if len(abc) <= 2:
            return tuple(sorted(abc, reverse=True))
        current = abc[0]
        second, first = _smallest2(abc[1:])
        if (second < current):
            re = (second, first)
        elif (current > first) and (second >= current):
            re = (current, first)
        else:
            re = (first, current)       
        return re
    return _smallest2(abc)
And secondly, I would use heapq.nsmallest instead of your implementation for searching:
import heapq
def flatten(li):
    for el in li:
        try:    # if strings can be in list, would have to check here
            for sub in flatten(el):
                yield sub
        except TypeError:
            yield el
def find(li):
    return tuple(heapq.nsmallest(2, flatten(li))[::-1])
If you are ok with a slightly different return value, feel free to drop the tuple and [::-1].
Alternative Implementation:
While I'd prefer the refactored code above for various reasons (e.g. robustness, expressiveness), here is an alternative implementation which arguably is more in line with your initial question. The main idea behind this implementation is to only check whether the first element is a list? If yes, flatten; if no, recursively go down the tail of the list:
def find(abc):
    try:                                                          # first element is list
        return find(abc[0] + abc[1:])                             #  -> flatten
    except:                                                       # first element is value
        if len(abc) <= 1: return abc                              # -> either end recursion
        return sorted(abc[:1] + find(abc[1:]), reverse=True)[-2:] # -> or recurse over tail
Note that the return type is slightly different (list instead of tuple). And you could replace sorted with heapq.nsmallest (which arguably is more efficient for small n).