Only one not so elegant part to get the first value of each dict:
first_values.append([i for i in item.values()][0]) 
It is copied from How to get the first value in a Python dictionary
Code
Simple code, for-loops and a dict. Explained with comments:
my_list = [
  {'xxxxx1': ['123.123.123.1','hey','hello']},
  {'xxxxx2': ['123.123.123.2','hi','HEY']},
  {'xxxxx3': ['123.123.123.3','foo','bar']},
  {'xxxxx3': ['123.123.123.2','foo','bar']}
]
# get the inner lists having IP as first element
first_values = []
for item in my_list:
    # for each element in the list (each dict), get the first value
    first_values.append([i for i in item.values()][0])
print(first_values)
# [['123.123.123.1', 'hey', 'hello'], ['123.123.123.2', 'hi', 'HEY'], ['123.123.123.3', 'foo', 'bar'], ['123.123.123.2', 'foo', 'bar']]
# convert the lists to a dict having IP as key, and words as value
ip_dict = {}
for element in first_values:
    ip = element[0]  # the fist element is the IP
    words = element[1:]  # the remaining element are words
    if ip not in ip_dict.keys():   # if IP not yet added (as key)
        ip_dict[ip] = words   # then add the new key, value pair
    else:
        ip_dict[ip] += words  # otherwise add the words to the existing value, which is a list of words
print(ip_dict)
# {'123.123.123.1': ['hey', 'hello'], '123.123.123.2': ['hi', 'HEY', 'foo', 'bar'], '123.123.123.3': ['foo', 'bar']}
From here you have a solid data structure as result.
The ip_dict can be pretty-printed, e.g. using a for loop like:
for ip, words in ip_dict.items():
    print(f"{ip}\n{' '.join(words)}")