Searching for files in a specified directory
To improve readability I would try and break the code down into more functions and redefine your pre-determined text values as globals, such that you can save space in the actual function. Responses can be represented by a dictionary value with boolean/text key value pairs (or exception/text). Also certain UI options can be stored in a dictionary, with links to their associated functions.

# using 3 quotes mean you don't need to specify newlines
dir_tools_menu = '''
Which search characteristics would you like to use?
1. Search by name: N 
2. Search by extension: E 
3. Search by size: S
\tPlease enter your choice: '''
dir_tools_options = {"n":ui_search_by_name, 
                     "e":ui_search_by_extention, 
                     "s":ui_search_by_size}
error_response = {WindowsError:"Oops! Access denied.", 
                  ValueError:"Enter an numeric value."}
# add number of files for true
files_found_response = {False:"No file(s) found", 
                        True:"{} file(s) found"}
# add filename
file_found_response = {False:"File {} not found",
                       True:"File {} found"}
file_exists_response ={ False:"Path does not exist.", 
                         True:"Path Found"}
# add choice for true
valid_ui_response = {False:"Invalid choice.", 
                      True:"You choose {}."}


Now that we have a collection of text values lets make a function to standardize print outputs, such that you don't have to write all those stars everywhere, and you can feel assured that they will produce even length lines.

line_length = 40
# or you can have a funky pattern like "`-._.-'-._...
line_pad = "*"*line_length 

def my_print(text, *params):
    # len(params) must match the count of "{}" in the text so this will not crash
    # Perhaps add a check to assert this case
    message = text.format(*params)
    offset = line_length/2 - len(message)/2
    if offset &gt; 0 and offset + len(message) &lt; line_length:
        print(line_pad[:offset] + message + line_pad[offset+len(message):])
    # in the case that a line is larger than the formatting, you can just print the line.
    # its gonna look gross regardless
    else:
        print(message)


Lets also make a simple yes/no function.

yes = ("yes", "y","1")
no = ("no", "n", "0")
def ask_yes_no(question):
    answer = ''
    while not answer in yes + no:
        answer = input(question).lower()
        if not answer in yes + no:
            my_print(valid_ui_response[False])
        else:
            my_print(valid_ui_response[True], return_to_menu)
            # True - yes, False - no
            return answer in yes


Now your main method boils down to..

quit_question = "Quit Dir Tools? "

def dir_tools(file_path):
    if os.path.exists(file_path):
        my_print(file_exists_response[True] )
    else:
        my_print(file_exists_response[False])
        return
    quit_dir_tools = False
    while not quit_dir_tools:
        answer = input(dir_tools_menu).lower()
        if answer not in dir_tools_options:
            my_print(valid_ui_response[False])
        else:
            my_print(valid_ui_response[True],answer)
            dir_tools_options[answer](file_path)
        quit_dir_tools = ask_yes_no(quit_question)


Now for the actual important functions.. I'll just do one example to show the try catch responses,..

ui_sbn_question = 'Enter file name: '
return_question = "Return to main menu? "

def ui_search_by_name(file_path):
    return_to_menu = False
    while not return_to_menu:
        name = input(ui_sbn_question)
        try:
            sbn_response = search_by_name(name, file_path)
            if not sbn_response:
                my_print(file_found_response[False], name)
            else:
                my_print(file_found_response[True], name)
                # assuming that this isnt a boolean
                my_print(sbn_response)
        except WindowsError:
            my_print(error_response[WindowsError])
        return_to_menu = ask_yes_no(return_question)