2-player Tic-Tac-Toe game
You probably forgot to test for this, but there's a bug in your program.

def x_move(i):
    if board[i] == 'X' or board[i] == 'O':
        return print('Already taken!')
    else:
        del board[i]
        board.insert(i,'X')
def o_move(i):
    if board[i] == 'X' or board[i] == 'O':
        return print('Already taken!')
    else:
        del board[i]
        board.insert(i,'O')


For starters, you should move this into a single function which takes the player as argument. This way a single function can be used for both players and this will save you from having to fix the bug twice. Code duplication is bad.

An obvious, not necessarily pretty, solution:

def any_move(i, player_character):
    if not isinstance(board[i], int):
        return print('Already taken!')
    else:
        del board[i]
        board.insert(i, player_character)


This checks whether the value picked on the board is an integer. If it's not, it has already been taken by either X, O or whatever player characters you're using at that moment.

But the real problem is this will skip a turn on invalid input. If I pick 4 with X in one turn and pick the same tile with O a turn later, O will be missing out a turn. I imagine there should be a loop in there checking whether valid input has been inserted yet. If not, stay in the loop. If valid input is inserted, make the actual move.

I'm talking about valid input here, not just whether the input is 0 - 8. Your program will crash if I enter something invalid, like b or 11. The first is not an integer and the second is out of range. It crashes on no input (just hit enter) as well. You should at least capture those exceptions.